package com.example.teesystem.filter;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.teesystem.common.cache.UserCache;
import com.example.teesystem.common.exception.CustomException;
import com.example.teesystem.common.utils.AuthenticationUtil;
import com.example.teesystem.common.utils.ResultCode;
import com.example.teesystem.entity.AuthenticationInfo;
import com.example.teesystem.entity.User;
import com.example.teesystem.service.UserService;
import com.example.teesystem.common.utils.TokenUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 拦截器
 * @author pxr
 * @data 2022/3/23 10:08
 */

@Component
@RequiredArgsConstructor
public class MyHandlerInterceptor implements HandlerInterceptor {
    private static final ThreadLocal<Integer> tl=new ThreadLocal<>();

    private final UserService userService;
    private final UserCache userCache;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        if(HttpMethod.OPTIONS.matches(request.getMethod())) {
            return true;
        }
        
        String token;
        int myUid,uid;
        try{
            token = request.getHeader("token");
            uid = request.getIntHeader("uid");
            myUid = Integer.parseInt(JWT.decode(token).getAudience().get(0));
            System.out.println(token);
            System.out.println(myUid);
        }catch (Exception e){
            System.out.println(e.getMessage());
            throw new CustomException(ResultCode.HEADER_ERROR.getMsg(),ResultCode.HEADER_ERROR.getCode());
        }
        if(uid != myUid){
            throw new CustomException(ResultCode.IDENTITY_ERROR_LOGIN_AGAIN.getMsg(), ResultCode.IDENTITY_ERROR_LOGIN_AGAIN.getCode());
        }
        User user = UserCache.userMap.get(myUid);
        if(user==null){
            throw new CustomException(ResultCode.LOGIN_AGAIN.getMsg(),ResultCode.LOGIN_AGAIN.getCode());
        }
        if(!AuthenticationUtil.isEffective(myUid)){
            throw new CustomException(ResultCode.TIME_OUT.getMsg(),ResultCode.TIME_OUT.getCode());
        }
        JWTVerifier jwtVerifier;

        jwtVerifier = JWT.require(Algorithm.HMAC256(TokenUtil.KEY)).build();
        try{
            jwtVerifier.verify(token);
        }catch (JWTVerificationException e){
            throw new CustomException(ResultCode.LOGIN_AGAIN.getMsg(),ResultCode.LOGIN_AGAIN.getCode());
        }
//        if(AuthenticationUtil.isExist(myUid)){
//            AuthenticationInfo authenticationInfo = AuthenticationUtil.getAuthenticationInfo(myUid);
//            if(token.equals(authenticationInfo.getToken())){
//                //验证token
//                jwtVerifier = JWT.require(Algorithm.HMAC256(TokenUtil.KEY)).build();
//                try{
//                    jwtVerifier.verify(token);
//                }catch (JWTVerificationException e){
//                    throw new CustomException(ResultCode.LOGIN_AGAIN.getMsg(),ResultCode.LOGIN_AGAIN.getCode());
//                }
//            }else {
//                throw new CustomException(ResultCode.LOGIN_AGAIN.getMsg(),ResultCode.LOGIN_AGAIN.getCode());
//            }
//        }else {
//            jwtVerifier = JWT.require(Algorithm.HMAC256(TokenUtil.KEY)).build();
//            try{
//                jwtVerifier.verify(token);
//            }catch (JWTVerificationException e){
//                throw new CustomException(ResultCode.LOGIN_AGAIN.getMsg(),ResultCode.LOGIN_AGAIN.getCode());
//            }
//        }
        tl.set(myUid);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView){
        tl.remove();
    }

    public static int getUid(){
        return tl.get();
    }

}
